#include <iostream>
#include <sstream>
#include <string.h>
#include <stdlib.h>
#include "OperationParser.h"

OperationParser::OperationParser() {
	this->clearRequest();
}

OperationParser::~OperationParser() {
}

bool OperationParser::parse(string line) {
	bool validLine = true;
	this->clearRequest();

	if (line == "list") {
		this->request.operation = LIST;
	} else if (line == "help") {
		this->request.operation = HELP;
	} else if (line == "exit") {
		this->request.operation = EXIT;
	} else if ((line.find("add ") == 0) && (line.length() > 4)) {
		this->request.operation = ADD;
		this->populateRequest(line.substr(4));
	} else if ((line.find("search ") == 0) && (line.length() > 7)) {
		this->request.operation = SEARCH;
		this->request.record.id = atoi(line.substr(7).c_str());
	} else if ((line.find("delete ") == 0) && (line.length() > 7)) {
		this->request.operation = DELETE;
		this->request.record.id = atoi(line.substr(7).c_str());
	} else {
		validLine = false;
	}

	return validLine;
}

RequestMessage OperationParser::getRequest() {
	return this->request;
}

void OperationParser::clearRequest() {
	this->request.operation = UNKNOWN;
	this->request.record.id = 0;
	strcpy(this->request.record.name, "");
	strcpy(this->request.record.address, "");
	strcpy(this->request.record.phone, "");
}

void OperationParser::populateRequest(const string &raw) {
	vector<string> values = this->splitString(raw, '\'');
	int size = values.size();

	if (size >= 2) {
		strcpy(this->request.record.name, values[1].c_str());
	}

	if (size >= 3) {
		strcpy(this->request.record.address, values[2].c_str());
	}

	if (size >= 4) {
		strcpy(this->request.record.phone, values[3].c_str());
	}

	if (size >= 5) {
		this->request.record.id = atoi(values[4].c_str());
	}
}

vector<string>& OperationParser::splitString(const string &s, char delim, vector<string> &elems) {
    stringstream ss(s);
    string item;
    while(getline(ss, item, delim)) {
    	if (!this->isWhiteSpace(item)) {
    		elems.push_back(item);
    	}
    }

    return elems;
}

vector<string> OperationParser::splitString(const string &s, char delim) {
    vector<string> elems;

    return this->splitString(s, delim, elems);
}

bool OperationParser::isWhiteSpace(const string &s) {
	if (s.empty()) {
		return false;
	}

	bool whiteSpace = true;
	for (unsigned int i = 0; i < s.size(); i++) {
		if (s[i] != ' ') {
			whiteSpace = false;
			break;
		}
	}

	return whiteSpace;
}
